package com.lagou;

import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.IndicesClient;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@SpringBootTest
@RunWith(SpringRunner.class)
public class ESTestIndex {

    @Autowired
    private RestHighLevelClient client;

    private final static String INDEX_NAME = "elasticsearch_test";


    //创建索引库
    /*
    PUT /elasticsearch_test
    {
        "settings": {},
        "mappings": {
            "properties": {
                "description": {
                    "type": "text",
                    "analyzer": "ik_max_word"
                },
                "name": {
                    "type": "keyword"
                },
                "pic": {
                    "type": "text",
                    "index": false
                },
                "studymodel": {
                    "type": "keyword"
                }
            }
        }
    }
    */
    @Test
    public void testCreateIndex() throws IOException {
        //创建一个索引创建请求对象
        CreateIndexRequest createIndexRequest = new CreateIndexRequest(INDEX_NAME);
        //设置映射
        XContentBuilder builder = XContentFactory.jsonBuilder()
                .startObject()
                .field("properties")
                .startObject()
                .field("description")
                .startObject().field("type","text").field("analyzer","ik_max_word").endObject()
                .field("name").startObject().field("type","keyword").endObject()
                .field("pic").startObject().field("type","text").field("index",false).endObject()
                .field("studymodel").startObject().field("type", "keyword").endObject()
                .endObject()
                .endObject();
        createIndexRequest.mapping("doc",builder);
        //操作索引的客户端
        IndicesClient indices = client.indices();
        CreateIndexResponse createIndexResponse = indices.create(createIndexRequest, RequestOptions.DEFAULT);
        //得到相应
        boolean acknowledged = createIndexResponse.isAcknowledged();
        System.out.println(acknowledged);
    }

    //删除索引
    @Test
    public void testDeleteIndex() throws IOException {
        //构建删除索引库的请求对象
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(INDEX_NAME);
        //操作索引的客户端
        IndicesClient indices = client.indices();
        AcknowledgedResponse deleteResponse = indices.delete(deleteIndexRequest, RequestOptions.DEFAULT);
        //得到相应
        boolean acknowledged = deleteResponse.isAcknowledged();
        System.out.println(acknowledged);
    }

    //添加文档
    /*
        POST /elasticsearch_test/_doc/1
        {
            "name": "spring cloud实战",
            "description": "本课程主要从四个章节进行讲解： 1.微服务架构入门 2.spring cloud 基
            础入门 3.实战Spring Boot 4.注册中心eureka。",
            "studymodel":"201001",
            "timestamp": "2020-08-22 20:09:18",
            "price": 5.6
        }
     */
    @Test
    public void testAddDoc() throws IOException {
        //准备索引请求对象
        //IndexRequest indexRequest = new IndexRequest(INDEX_NAME,"doc");
        IndexRequest indexRequest = new IndexRequest(INDEX_NAME);
        //indexRequest.id("1"); 不设置自动生成
        //文档内容 准备json数据
        Map<String,Object> jsonMap = new HashMap<>();
        jsonMap.put("name","spring cloud实战");
        jsonMap.put("description","本课程主要从四个章节进行讲解： 1.微服务架构入门 2.spring cloud 基础入门 3.实战Spring Boot 4.注册中心eureka。");
        jsonMap.put("studymodel","201001");
        jsonMap.put("timestamp","2020-08-22 20:09:18");
        jsonMap.put("price",5.6);
        indexRequest.source(jsonMap);
        //执行请求
        IndexResponse indexResponse = client.index(indexRequest,RequestOptions.DEFAULT);
        DocWriteResponse.Result result = indexResponse.getResult();
        System.out.println(result);
    }

    //查询文档
    @Test
    public void testGetDoc() throws IOException {
        //查询请求对象
        GetRequest getRequest = new GetRequest(INDEX_NAME, "kTPs73oBmNblcBs-aihv");
        GetResponse getResponse = client.get(getRequest,RequestOptions.DEFAULT);
        //得到文档内容
        Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();
        System.out.println(sourceAsMap);
    }

    //搜索全部记录
    /*
        GET /elasticsearch_test/_search
        {
            "query":{
            "match_all":{}
            }
        }
    */
    @Test
    public void testSearchAll() throws IOException {
        //搜索请求对象
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        //搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //设置搜索方法
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        searchSourceBuilder.fetchSource(new String[]{"name","price","timestamp"},new String[]{});
        //请求对象设置搜索源对象
        searchRequest.source(searchSourceBuilder);
        //使用client 执行搜索
        SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
        //搜索结果
        SearchHits hits = searchResponse.getHits();
        //匹配到的总记录数
        TotalHits totalHits = hits.getTotalHits();
        //得到的匹配度高的文档
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit searchHit : searchHits) {
            System.out.println(searchHit.getSourceAsMap());
            System.out.println("id:"+searchHit.getId());
        }
    }

    @Test
    public void testTermQuery() throws IOException {
        //搜索请求对象
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        //搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //设置搜索方法
        searchSourceBuilder.query(QueryBuilders.termQuery("name","spring"));
        searchSourceBuilder.fetchSource(new String[]{"name","price","timestamp"},new String[]{});
        //请求对象设置搜索源对象
        searchRequest.source(searchSourceBuilder);
        //使用client 执行搜索
        SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
        //搜索结果
        SearchHits hits = searchResponse.getHits();
        //匹配到的总记录数
        TotalHits totalHits = hits.getTotalHits();
        //得到的匹配度高的文档
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit searchHit : searchHits) {
            System.out.println(searchHit.getSourceAsMap());
            System.out.println("id:"+searchHit.getId());
        }
    }

    @Test
    public void testSearchAllPage() throws IOException {
        //搜索请求对象
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        //搜索源构建对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //设置搜索方法
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        searchSourceBuilder.fetchSource(new String[]{"name","price","timestamp"},new String[]{});
        //设置分页参数
        int page = 1;
        int size = 2;
        int from = (page - 1) * size;
        searchSourceBuilder.from(from);
        searchSourceBuilder.size(size);
        //设置排序
        searchSourceBuilder.sort("price", SortOrder.DESC);
        //请求对象设置搜索源对象
        searchRequest.source(searchSourceBuilder);
        //使用client 执行搜索
        SearchResponse searchResponse = client.search(searchRequest,RequestOptions.DEFAULT);
        //搜索结果
        SearchHits hits = searchResponse.getHits();
        //匹配到的总记录数
        TotalHits totalHits = hits.getTotalHits();
        //得到的匹配度高的文档
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit searchHit : searchHits) {
            System.out.println(searchHit.getSourceAsMap());
            System.out.println("id:"+searchHit.getId());
        }
    }

}
